Skip to content
View Article Network

ASP.NET Core Namespace Conflict Issues

Scenario

Recently, while refactoring someone else's project, I decided to be clever and renamed a project ending in "SYS" to ".System". That was when the tragedy struck: the project would no longer compile. Below is a simulation of the scenario.

The project namespace was "TestNameSpace.Web". During compilation, a large number of errors appeared in the Razor files.

razor compilation errors

I initially thought it was a DLL reference issue, but after carefully examining the error messages, I realized something was wrong. The message was not "The type or namespace name 'Threading' could not be found in the namespace 'System'", but rather "The type or namespace name 'Threading' could not be found in the namespace 'TestNameSpace.System'". "TestNameSpace.System.Threading"??? It appears to be caused by a namespace conflict.

Global Using Directives

C# 10, supported by .NET 6, provides a new feature called "Global Using Directives". It allows you to set global usings and provides implicit global usings. In the image below, the grayed-out items are defaults that cannot be adjusted, but they can be extended.

global using directives settings

The corresponding XML structure in the project file is shown below. The top part determines whether to enable implicit global usings, and the bottom part shows additional global usings.

csproj global usings

After building the project, you can find a file named "{ProjectName}.GlobalUsings.g.cs" under the "obj/{Configuration}/{.NET Version}" folder.

obj folder global usings

When no other implicit global usings are set, the file content looks like this:

csharp
// <auto-generated/>
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Threading;
global using global::System.Threading.Tasks;

Is the Problem Solved?

After disabling implicit global usings, I found that it still would not compile. I subsequently changed the framework version to .NET 5, which does not support "Global Using Directives", and it still failed to compile. This indicates that the global using settings for Razor files come from elsewhere. Finally, I opened "obj\Debug\net5.0\Razor\Pages\Index.cshtml.g.cs". As shown in the image below, I discovered that in addition to the usings set in "_ViewStart.cshtml", there are other namespaces used by default, and they differ from the content in Global Usings. I currently suspect these might be hardcoded.

razor generated source usings

From the image above, we can see that the Root Namespace for each Razor file is defined in "_ViewStart.cshtml". By default, the project name is used as the Root Namespace. Therefore, you can refer to the code below to change the defined namespace to the required one. However, please note that the namespace set in "_ViewStart.cshtml" must be the same as the namespace in "{Page}.cshtml.cs". It would be strange if you changed the namespaces for all files related to Razor but kept them different from the namespaces of other files in the project. Even though "Project Name", "Assembly", and "Root Namespace" do not usually need to be consistent, in this case, it is best to avoid using keywords from the start.

csharp
@using TestNamespace.Sys.Web
@* Change System to Sys here so that all Razor files will apply this namespace *@
@namespace TestNamespace.Sys.Web.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

TIP

The path mentioned above was only found in .NET 5. I have not yet found where .NET 6 stores the "\Razor\Pages{Page Name}.cshtml.g.cs" files generated during the compilation process.

Conclusion

When creating an ASP.NET Core project that uses Razor files, it is recommended that the project name does not contain "System" or "Microsoft".

Changelog

    • Initial version created.